package com.autumn.platform.dao.dialect;

import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.SQLException;

import javax.sql.DataSource;

import org.springframework.jdbc.support.DatabaseMetaDataCallback;
import org.springframework.jdbc.support.JdbcUtils;
import org.springframework.jdbc.support.MetaDataAccessException;

import com.autumn.platform.dao.dialect.impl.H2;
import com.autumn.platform.dao.dialect.impl.MySQL;
import com.autumn.platform.dao.dialect.impl.Oracle;

public abstract class Dialects {

    private Dialects() {}

    /**
     * 根据数据源获取方言
     * 
     * @param dataSource 数据源
     * @return 数据库方言
     */
    public static IDialect getDialect(DataSource dataSource) {
        try {
            Object dialect = JdbcUtils.extractDatabaseMetaData(dataSource, new DatabaseMetaDataCallback() {
                @Override
                public Object processMetaData(DatabaseMetaData dbmd) throws SQLException, MetaDataAccessException {
                    return getDialect(dbmd.getDatabaseProductName());
                }
            });
            return (IDialect) dialect;
        } catch (MetaDataAccessException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 根据数据库连接获取方言
     * 
     * @param conn 数据库连接
     * @return 数据库方言
     */
    public static IDialect getDialect(Connection conn) {
        try {
            String databaseProductName = conn.getMetaData().getDatabaseProductName();
            return getDialect(databaseProductName);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 根据数据库产品名称获取数据库方言
     * 
     * @param databaseProductName 数据库产品名称
     * @return 数据库方言
     */
    public static IDialect getDialect(String databaseProductName) {
        String name = databaseProductName.toLowerCase();
        if (-1 != name.indexOf("mysql")) {
            return MySQL.getInstance();
        } else if (-1 != name.indexOf("oracle")) {
            return Oracle.getInstance();
        } else if (-1 != name.indexOf("h2")) {
            return H2.getInstance();
        } else if (-1 != name.indexOf("db2")) {
            return H2.getInstance();
        } else {
            throw new UnsupportedOperationException("not found the database dialect.");
        }
    }
}
